package com.dwxt.community.aiequipment.util;

import com.dwxt.common.base.YesOrNo;
import com.dwxt.community.aiequipment.aibin.AiBinException;
import com.dwxt.community.aiequipment.aibin.Clean;
import com.dwxt.community.aiequipment.aibin.entity.AiBinRecordInfo;
import com.dwxt.community.aiequipment.aibin.entity.AiBinVerifyInfo;
import com.dwxt.community.aiequipment.aibin.entity.TrashCan;
import com.dwxt.community.aiequipment.aibin.entity.TrashInner;
import com.dwxt.community.aiequipment.aibin.entity.enumeration.FaultStatus;
import com.dwxt.community.aiequipment.aibin.entity.enumeration.WorkStatus;
import com.dwxt.community.aiequipment.aibin.service.TrashCanService;
import com.dwxt.community.aiequipment.enumeration.*;
import com.dwxt.community.aiequipment.sellmachine.entity.SellMachine;
import com.dwxt.community.aiequipment.sellmachine.entity.SellMachineBreakdownRecord;
import com.dwxt.community.aiequipment.sellmachine.entity.SellMachineNetpay;
import com.dwxt.community.aiequipment.sellmachine.entity.enumeration.PayTypeEnum;
import com.dwxt.community.entity.TrashIntegralRecoad;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.UUID;

/**
 * @author
 * @program: intelligentcity
 * @description: 解析分类桶返回数据为java对象
 * @create: 2020/04/15
 */
public class ParseFenleiUtil {

    private static Logger logger = LoggerFactory.getLogger(ParseFenleiUtil.class);

    /**
     * 验证数据格式
     */
    public static int verifyFormat(int[] shakeHandInts) {
        int parseStatus;
        if (shakeHandInts == null || shakeHandInts.length == 0) {
            parseStatus = ResStatueEnum.DATA_NULL.getCode();
        } else {
            int concatLength = DataHandler.unionLowHigh(shakeHandInts[MainBoardConstant.LENGTH_LOW],
                    shakeHandInts[MainBoardConstant.LENGTH_HIGH]);
            int byteLength = shakeHandInts.length;
            if (concatLength == byteLength) {
                // 验证起始码
                int lowQsm = shakeHandInts[MainBoardConstant.QSM_LOW];
                int highQsm = shakeHandInts[MainBoardConstant.QSM_HIGH];
                if (lowQsm == MainBoardConstant.MB_QSM_LOW && highQsm == MainBoardConstant.MB_QSM_HIGH) {
                    // 验证CRC
                    if (DataHandler.crcDeviceData(shakeHandInts)) {
                        parseStatus = ResStatueEnum.OK.getCode();
                    } else {
                        parseStatus = ResStatueEnum.CRC_ERROR.getCode();
                        logger.error("智能设备请求数据CRC验证失败");
                    }
                } else {
                    parseStatus = ResStatueEnum.START_CODE_ERROR.getCode();
                    logger.error(ResStatueEnum.START_CODE_ERROR.getMsg());
                }
            } else {
                parseStatus = ResStatueEnum.LENGTH_ERROR.getCode();
                logger.error(ResStatueEnum.LENGTH_ERROR.getMsg());
            }
        }
        return parseStatus;
    }

    /**
     * 解析经度
     */
    public static float parseLng(int[] shakeHandsInts) {
        long j_one = shakeHandsInts[WsConstant.FENLEI_WS_JD_START + 3];
        long j_two = shakeHandsInts[WsConstant.FENLEI_WS_JD_START + 2];
        long j_three = shakeHandsInts[WsConstant.FENLEI_WS_JD_START + 1];
        long j_fore = shakeHandsInts[WsConstant.FENLEI_WS_JD_START];
        double jingdu = ((double) ((j_one > 0 ? j_one : j_one + 256) << 24
                | (j_two > 0 ? j_two : j_two + 256) << 16
                | (j_three > 0 ? j_three : j_three + 256) << 8
                | (j_fore > 0 ? j_fore : j_fore + 256))) / 100000;
        //经度GPS数据校准算法
        BigDecimal deviceGpsLngBigDecimal = new BigDecimal(jingdu);
        BigDecimal deviceGpsLngTitle = deviceGpsLngBigDecimal.divide(new BigDecimal(100), 0, BigDecimal.ROUND_DOWN);
        BigDecimal floatValue = deviceGpsLngBigDecimal.subtract(new BigDecimal(deviceGpsLngTitle.multiply(new BigDecimal(100)).intValue()));
        return deviceGpsLngTitle.add(new BigDecimal(floatValue.divide(new BigDecimal(60), 6, BigDecimal.ROUND_DOWN).floatValue())).floatValue();
    }

    /**
     * 解析纬度
     */
    public static float parseLat(int[] shakeHandsInts) {
        // 纬度
        long w_one = shakeHandsInts[WsConstant.FENLEI_WS_WD_START + 3];
        long w_two = shakeHandsInts[WsConstant.FENLEI_WS_WD_START + 2];
        long w_three = shakeHandsInts[WsConstant.FENLEI_WS_WD_START + 1];
        long w_fore = shakeHandsInts[WsConstant.FENLEI_WS_WD_START];
        double weidu = ((double) ((w_one > 0 ? w_one : w_one + 256) << 24
                | (w_two > 0 ? w_two : w_two + 256) << 16
                | (w_three > 0 ? w_three : w_three + 256) << 8
                | (w_fore > 0 ? w_fore : w_fore + 256))) / 1000000;// 纬度
        //维度GPS数据校准算法
        BigDecimal deviceGpsLatBigDecimal = new BigDecimal(weidu);
        BigDecimal deviceGpsLatTitle = deviceGpsLatBigDecimal.divide(new BigDecimal(100), 0, BigDecimal.ROUND_DOWN);
        BigDecimal floatValue1 = deviceGpsLatBigDecimal.subtract(deviceGpsLatTitle.multiply(new BigDecimal(100)));
        return deviceGpsLatTitle.add(new BigDecimal(floatValue1.divide(new BigDecimal(60), 6, BigDecimal.ROUND_DOWN).floatValue())).floatValue();
    }

    /**
     * 解析分类桶握手数据
     */
    public static TrashCan parseWs(TrashCanService trashCanService, int[] shakeHandsBytes) {

        TrashCan trashCan = new TrashCan();
        // 主板ID
        String deviceId = parseDeviceId(shakeHandsBytes, 4, 15);
        trashCan.setDeviceId(deviceId);

        // ICCID
        int[] iccIdBytes = DataHandler.subInts(shakeHandsBytes, 16, 25);
        String iccId = DataHandler.encodeHexStr(DataHandler.toByteArray(iccIdBytes));
        trashCan.setIccId(iccId);
        //经度
        float gpsLngFloat = parseLng(shakeHandsBytes);
        // trashCan.setDeviceGpsLng((double) gpsLngFloat);
        //纬度
        float gpsLatFloat = parseLat(shakeHandsBytes);
        // trashCan.setDeviceGpsLat((double) gpsLatFloat);
        //逗号拼接经纬度
        String gps = gpsLngFloat + "," + gpsLatFloat;
        trashCan.setLocation(gps);


        // 信号强度
        trashCan.setSignalIntensity(shakeHandsBytes[WsConstant.FENLEI_WS_XHQD_START]);
        // 固件版本
        trashCan.setFirmwareVersion(shakeHandsBytes[WsConstant.FENLEI_WS_GJBB_START]);
        // 充电电压
        int cddylow = shakeHandsBytes[WsConstant.FENLEI_WS_CDDY_START];
        int cddyhigh = shakeHandsBytes[WsConstant.FENLEI_WS_CDDY_START + 1];
        trashCan.setBatteryVoltage(DataHandler.unionLowHigh(cddylow, cddyhigh));

        // 充电电流
        int cddllow = shakeHandsBytes[WsConstant.FENLEI_WS_CDDL_START];
        int cddlhigh = shakeHandsBytes[WsConstant.FENLEI_WS_CDDL_START + 1];
        trashCan.setChargingCurrent(DataHandler.unionLowHigh(cddllow, cddlhigh));

        //日充电量
        int rcdllow = shakeHandsBytes[WsConstant.FENLEI_WS_RCDL_START];
        int rcdlhigh = shakeHandsBytes[WsConstant.FENLEI_WS_RCDL_START + 1];
        trashCan.setDailyCharge(DataHandler.unionLowHigh(rcdllow, rcdlhigh));

        //日用电量
        int rydllow = shakeHandsBytes[WsConstant.FENLEI_WS_RYDL_START];
        int rydlhigh = shakeHandsBytes[WsConstant.FENLEI_WS_RYDL_START + 1];
        trashCan.setDailyElectricity(DataHandler.unionLowHigh(rydllow, rydlhigh));

        //电池电压
        int dcdylow = shakeHandsBytes[WsConstant.FENLEI_WS_DCDY_START];
        int dcdyhigh = shakeHandsBytes[WsConstant.FENLEI_WS_DCDY_START + 1];
        trashCan.setBatteryVoltage(DataHandler.unionLowHigh(dcdylow, dcdyhigh));

        //主板温度
        trashCan.setMainboardTemperature(shakeHandsBytes[WsConstant.FENLEI_WS_ZBWD_START]);

        //电池温度
        trashCan.setBatteryTemperatur(shakeHandsBytes[WsConstant.FENLEI_WS_DCWD_START]);

        //分桶总数
        int ftzs = shakeHandsBytes[WsConstant.FENLEI_WS_FTZS_START];
        trashCan.setSortSum(ftzs);
        trashCan.setBinCount(ftzs);

        //故障状态
        AiBinException e;
        //握手时间
        Date currDate = new Date();
        trashCan.setWsTime(currDate);
        //是否满桶
        trashCan.setStatus(YesOrNo.NO);

        //内桶状态解析
        if (ftzs > 0) {
            ArrayList<TrashInner> trashInners = new ArrayList<>();
            for (int i = 0; i < ftzs; i++) {
                TrashInner trashInner = new TrashInner();
                trashInner.setDeviceNo(deviceId);
                trashInner.setSortNo(i);
                trashInner.setTdmId(i);
                trashInner.setCreateTime(currDate);
                trashInner.setUpdateTime(currDate);
                // 故障状态码
                int gzztStar = WsConstant.FENLEI_WS_GZZT_START;
                int gzzt = shakeHandsBytes[gzztStar + 6 * i];
                // 工做状态(正常状态)
                int zczt = shakeHandsBytes[gzztStar + 1 + 6 * i];
                //溫度
                if ((zczt & 0x01) == 0) {// 温度是否超限
                    int wd = shakeHandsBytes[gzztStar + 2 + 6 * i];
                    if (wd > 127) {
                        wd = wd - 256;
                    }
                    trashInner.setInnerTemperature(wd);
                } else {
                    trashInner.setInnerTemperature(100);
                }
                // 垃圾量
                int volume = shakeHandsBytes[gzztStar + i * 6 + 3];
                // 容量判断
                trashInner.setInnerVolume(Math.min(volume, 100));
                //实时重量
                int lowWeight = shakeHandsBytes[gzztStar + i * 6 + 4];
                int highWeight = shakeHandsBytes[gzztStar + i * 6 + 5];
                int weight = DataHandler.unionLowHigh(lowWeight, highWeight);
                //重量
                double sszlToD = (double) weight * 10;
                trashInner.setInnerWeight(sszlToD);
                // 判断发生哪种故障
                // 温度传感器断开
                if (gzzt == 0) {
                    trashInner.setFaultStatus("0");
                } else {
                    StringBuilder faultStatus = new StringBuilder();
                    if ((gzzt & 0x01) != 0) {
                        faultStatus.append(FaultStatus.TEMPERATURE_TRANSDUCER_INTERRUPT.getCode()).append(",");
                        e = new AiBinException();
                        e.setSORT_NO(i);
                        e.setERROR_TYPE(WsConstant.FENLEI_WDCGQ_GZ);
                        e.setID(UUID.randomUUID().toString());
                        e.setERROR_DESC(FaultStatus.TEMPERATURE_TRANSDUCER_INTERRUPT.getMsg());
                        e.setERROR_TIME(currDate);
                        e.setCREATE_USER_ID("system");
                        e.setDEVICE_ID(deviceId);
                        trashCan.getExceptions().add(e);
                    }
                    // 上限位故障
                    if ((gzzt & 0x40) != 0) {
                        faultStatus.append(FaultStatus.CEILING_ERROR.getCode()).append(",");
                        e = new AiBinException();
                        e.setSORT_NO(i);
                        e.setERROR_TYPE(WsConstant.FENLEI_SXW_GZ);
                        e.setID(UUID.randomUUID().toString());
                        e.setERROR_DESC(FaultStatus.CEILING_ERROR.getMsg());
                        e.setERROR_TIME(currDate);
                        e.setCREATE_USER_ID("system");
                        e.setDEVICE_ID(deviceId);
                        trashCan.getExceptions().add(e);
                    }
                    // 下限位故障
                    if ((gzzt & 0x80) != 0) {
                        faultStatus.append(FaultStatus.FLOOR_ERROR.getCode()).append(",");
                        e = new AiBinException();
                        e.setSORT_NO(i);
                        e.setERROR_TYPE(WsConstant.FENLEI_XXW_GZ);
                        e.setID(UUID.randomUUID().toString());
                        e.setERROR_DESC(FaultStatus.FLOOR_ERROR.getMsg());
                        e.setERROR_TIME(currDate);
                        e.setCREATE_USER_ID("system");
                        e.setDEVICE_ID(deviceId);
                        trashCan.getExceptions().add(e);
                    }
                    // 容量传感器断开
                    if ((gzzt & 0x02) != 0) {
                        faultStatus.append(FaultStatus.CAPACITY_TRANSDUCER_INTERRUPT.getCode()).append(",");
                        e = new AiBinException();
                        e.setSORT_NO(i);
                        e.setERROR_TYPE(WsConstant.FENLEI_RLCGQ_GZ);
                        e.setID(UUID.randomUUID().toString());
                        e.setERROR_DESC(FaultStatus.CAPACITY_TRANSDUCER_INTERRUPT.getMsg());
                        e.setERROR_TIME(currDate);
                        e.setCREATE_USER_ID("system");
                        e.setDEVICE_ID(deviceId);
                        trashCan.getExceptions().add(e);
                    }
                    // 称重系统故障
                    if ((gzzt & 0x04) != 0) {
                        faultStatus.append(FaultStatus.WEIGH_SYSTEM_ERROR.getCode()).append(",");
                        e = new AiBinException();
                        e.setSORT_NO(i);
                        e.setERROR_TYPE(WsConstant.FENLEI_CZCGQ_GZ);
                        e.setID(UUID.randomUUID().toString());
                        e.setERROR_DESC(FaultStatus.WEIGH_SYSTEM_ERROR.getMsg());
                        e.setERROR_TIME(currDate);
                        e.setCREATE_USER_ID("system");
                        e.setDEVICE_ID(deviceId);
                        trashCan.getExceptions().add(e);
                    }
                    // 电机断开
                    if ((gzzt & 0x10) != 0) {
                        faultStatus.append(FaultStatus.ELECTRICAL_MACHINERY_INTERRUPT.getCode()).append(",");
                        e = new AiBinException();
                        e.setSORT_NO(i);
                        e.setERROR_TYPE(WsConstant.FENLEI_DJDK_GZ);
                        e.setID(UUID.randomUUID().toString());
                        e.setERROR_DESC(FaultStatus.ELECTRICAL_MACHINERY_INTERRUPT.getMsg());
                        e.setERROR_TIME(currDate);
                        e.setCREATE_USER_ID("system");
                        e.setDEVICE_ID(deviceId);
                        trashCan.getExceptions().add(e);
                    }
                    // 电机短路
                    if ((gzzt & 0x20) != 0) {
                        faultStatus.append(FaultStatus.ELECTRICAL_MACHINERY_SHORT_OUT.getCode()).append(",");
                        e = new AiBinException();
                        e.setSORT_NO(i);
                        e.setERROR_TYPE(WsConstant.FENLEI_DJDL_GZ);
                        e.setID(UUID.randomUUID().toString());
                        e.setERROR_DESC(FaultStatus.ELECTRICAL_MACHINERY_SHORT_OUT.getMsg());
                        e.setERROR_TIME(currDate);
                        e.setCREATE_USER_ID("system");
                        e.setDEVICE_ID(deviceId);
                        trashCan.getExceptions().add(e);
                    }
                    trashInner.setFaultStatus(StringUtils.isBlank(faultStatus.toString())?"0":faultStatus.toString());
                }

                if (zczt == 0) {
                    trashInner.setWorkStatus("0");
                } else {
                    StringBuilder workStatus = new StringBuilder();
                    Clean clean;
                    // 温度超限
                    if ((zczt & 0x01) != 0 && (zczt & 0x02) == 0) {
                        if ((gzzt & 0x01) == 0) {
                            workStatus.append(WorkStatus.TEMPERATURE_OVERRUN.getCode()).append(",");
                            clean = new Clean();
                            clean.setId(UUID.randomUUID().toString());
                            clean.setDeviceId(deviceId);
                            clean.setSortNo(i);
                            clean.setFullTime(currDate);
                            clean.setCleanWeight(weight + "");
                            clean.setFullType(WsConstant.FULL_TYPE_TEMPERATURE);
                            trashCan.getSortList().add(clean);
                        }

                    }
                    // 容量超限
                    if ((zczt & 0x02) != 0 && (zczt & 0x04) == 0) {
                        if ((gzzt & 0x02) == 0) {
                            workStatus.append(WorkStatus.CAPACITY_FULL.getCode()).append(",");
                            trashCan.setStatus(YesOrNo.YES);
                            clean = new Clean();
                            clean.setId(UUID.randomUUID().toString());
                            clean.setDeviceId(deviceId);
                            clean.setCleanWeight(weight + "");
                            clean.setSortNo(i);
                            clean.setFullTime(currDate);
                            clean.setCleanStatus("N");
                            clean.setFullType(WsConstant.FULL_TYPE_VOLUMN);
                            trashCan.getSortList().add(clean);
                        }
                    }
                    // 重量超限
                    if ((zczt & 0x04) != 0 && (zczt & 0x02) == 0) {
                        if ((gzzt & 0x04) == 0) {
                            workStatus.append(WorkStatus.WEIGH_FULL.getCode()).append(",");
                            trashCan.setStatus(YesOrNo.YES);
                            clean = new Clean();
                            clean.setId(UUID.randomUUID().toString());
                            clean.setDeviceId(deviceId);
                            clean.setSortNo(i);
                            clean.setFullTime(currDate);
                            clean.setCleanWeight(weight + "");
                            clean.setCleanStatus("N");
                            clean.setFullType(WsConstant.FULL_TYPE_WEIGHT);
                            trashCan.getSortList().add(clean);
                        }
                    }
                    // 缺水
                    if ((zczt & 0x20) != 0 && (zczt & 0x22) == 0) {
                        workStatus.append(WorkStatus.HYDROPENIC.getCode()).append(",");
                        clean = new Clean();
                        clean.setId(UUID.randomUUID().toString());
                        clean.setDeviceId(deviceId);
                        clean.setSortNo(i);
                        clean.setFullTime(currDate);
                        clean.setCleanWeight(weight + "");
                        clean.setFullType(WsConstant.HYDROPENIC);
                        trashCan.getSortList().add(clean);
                    }
                    trashInner.setWorkStatus(StringUtils.isBlank(workStatus.toString())?"0":workStatus.toString());
                }
                trashInners.add(trashInner);
            }
            trashCan.setTrashInners(trashInners);
        }
        return trashCan;
    }


    /**
     * 设备ID
     *
     * @param data
     * @return
     */
    public static String parseDeviceId(int[] data, int str, int end) {
        int[] binIdBytes = DataHandler.subInts(data, str, end);
        return DataHandler.encodeHexStr(DataHandler.toByteArray(binIdBytes)).toUpperCase();
    }

    /**
     * 数据长度
     *
     * @param data
     * @return
     */
    public static int parseDataLength(int[] data) {
        int low = data[BaseProtocolOffsetCode.REPLY_LENGTH_LOW];
        int high = data[BaseProtocolOffsetCode.REPLY_LENGTH_HIGH];
        return DataHandler.unionLowHigh(low, high);
    }

    /**
     * 解析验证数据
     */
    public static AiBinVerifyInfo parseVerify(int[] verifyBytes) {
        AiBinVerifyInfo aiBinVerifyInfo = new AiBinVerifyInfo();
        //获取设备ID
        String deviceId = parseDeviceId(verifyBytes, 4, 15);
        //获取数据长度
        int length = parseDataLength(verifyBytes);
        aiBinVerifyInfo.setDeviceId(deviceId);
        //获取卡号数组
        int[] cordNo = DataHandler.subInts(verifyBytes, VerifyOffsetCode.cardNoStar, length - VerifyOffsetCode.cardNoEnd);
        aiBinVerifyInfo.setCordNoArr(cordNo);
        //卡号转字符串
        String cordNoStr = DataHandler.toCharArrayStr(cordNo);
        aiBinVerifyInfo.setCordNo(cordNoStr);
        //返回解析结果
        return aiBinVerifyInfo;
    }


    /**
     * 解析投递数据
     */
    public static AiBinRecordInfo parseRecord(int[] recordInts) throws ParseException {
        AiBinRecordInfo aiBinRecordInfo = new AiBinRecordInfo();
        //获取设备号
        String deviceId = parseDeviceId(recordInts, 4, 15);
        aiBinRecordInfo.setDeviceId(deviceId);
        //获取长度
        int len = parseDataLength(recordInts);

        int dynamicOffset = BaseProtocolOffsetCode.DEVICE_END_STAR;

        ArrayList<TrashIntegralRecoad> tirs = new ArrayList<>();
        while (dynamicOffset + recordInts[dynamicOffset] + 2 <= len) {
            int recordLen = recordInts[dynamicOffset];
            TrashIntegralRecoad trashIntegralRecoad = new TrashIntegralRecoad();
            trashIntegralRecoad.setTrashType(recordInts[dynamicOffset + 1]);
            int low = recordInts[dynamicOffset + 4];
            int high = recordInts[dynamicOffset + 5];
            int weight = DataHandler.unionLowHigh(low, high) * 10;
            trashIntegralRecoad.setDeliverWeight(weight);
            trashIntegralRecoad.setCreateTime(parseDate(recordInts[dynamicOffset + 6], recordInts[dynamicOffset + 7], recordInts[dynamicOffset + 8], recordInts[dynamicOffset + 9], recordInts[dynamicOffset + 10], recordInts[dynamicOffset + 11]));
            int[] userIdArr = DataHandler.subInts(recordInts, dynamicOffset + 12, dynamicOffset + recordLen - 2);
            String userIdStr = DataHandler.toCharArrayStr(userIdArr);
            trashIntegralRecoad.setDelivererId(userIdStr);
            trashIntegralRecoad.setDeviceId(deviceId);
            tirs.add(trashIntegralRecoad);
            //设置下一个记录长度的位置
            dynamicOffset += recordLen;
        }
        aiBinRecordInfo.setTrashIntegralRecoads(tirs);
        return aiBinRecordInfo;
    }


    /******************************************************************
     *  售卖机
     ********************************************************************/
    /**
     * 解析售卖机握手数据
     *
     * @return
     */
    public static SellMachine parseSmjWs(int[] dataInts) {
        SellMachine sellMachine = new SellMachine();

        String deviceId = parseDeviceId(dataInts, 4, 15);
        sellMachine.setDeviceId(deviceId);

        //经度
        // sellMachine.setGpsLng((double) parseLng(dataInts));  不准确 已去掉

        //纬度
        // sellMachine.setGpsLat((double) parseLat(dataInts));

        int[] iccidInts = DataHandler.subInts(dataInts, 25, 34);
        String iccId = DataHandler.encodeHexStr(DataHandler.toByteArray(iccidInts));
        sellMachine.setIccid(iccId);

        sellMachine.setSignalIntensity(dataInts[35]);
        sellMachine.setFirmwareVersion(dataInts[36]);
        sellMachine.setChargingCurrent(DataHandler.unionLowHigh(dataInts[37], dataInts[38]));
        sellMachine.setDailyCharge(DataHandler.unionLowHigh(dataInts[39], dataInts[40]));
        sellMachine.setDailyElectricity(DataHandler.unionLowHigh(dataInts[41], dataInts[42]));
        sellMachine.setBatteryVoltage(DataHandler.unionLowHigh(dataInts[43], dataInts[44]));
        sellMachine.setSunVoltage(DataHandler.unionLowHigh(dataInts[45], dataInts[46]));
        sellMachine.setBatteryVoltage(DataHandler.unionLowHigh(dataInts[47], dataInts[48]));
        sellMachine.setMainboardTemperature(dataInts[49]);
        sellMachine.setBatteryTemperature(dataInts[50]);
        sellMachine.setUserType(dataInts[51]);
        sellMachine.setDeviceType(dataInts[52]);

        return sellMachine;
    }

    /**
     * 解析售卖机故障状态
     *
     * @param dataInts
     * @return
     */
    public static SellMachineBreakdownRecord parseSmjBreakdown(int[] dataInts) throws ParseException {
        SellMachineBreakdownRecord sellMachineBreakdownRecord = new SellMachineBreakdownRecord();
        sellMachineBreakdownRecord.setDeviceId(parseDeviceId(dataInts, 4, 15));
        sellMachineBreakdownRecord.setBreakdownStatus(dataInts[17]);
        sellMachineBreakdownRecord.setBreakdownType(dataInts[18]);
        sellMachineBreakdownRecord.setBreakdownCode(dataInts[19]);
        sellMachineBreakdownRecord.setBreakdownTime(parseDate(dataInts[20],dataInts[21],dataInts[22],dataInts[23],dataInts[24],dataInts[25]));
        return sellMachineBreakdownRecord;
    }

    /**
     * 售卖机支付
     *
     * @param dataInts
     * @return
     */
    public static SellMachineNetpay parseNetPay(int[] dataInts) {

        switch (dataInts[16]) {
            case 0:
                return parsePayUrl(dataInts);
            case 1:
                return parsePayStatus(dataInts);
            case 2:
                return parseAisleInfo(dataInts);
            case 3:
                return parseIntegralConversion(dataInts);
            default:
                return null;
        }
    }

    /**
     * 解析积分兑换数据
     *
     * @param dataInts
     * @return
     */
    private static SellMachineNetpay parseIntegralConversion(int[] dataInts) {
        SellMachineNetpay sellMachineNetpay = new SellMachineNetpay();
        sellMachineNetpay.setNetPayType(dataInts[16]);
        sellMachineNetpay.setPayType(PayTypeEnum.CONVERSION.getCode());
        sellMachineNetpay.setAisle(parseAisle(dataInts));
        sellMachineNetpay.setDeviceId(parseDeviceId(dataInts, 4, 15));
        sellMachineNetpay.setCardNo(parseCardNo(dataInts));
        return sellMachineNetpay;
    }

    /**
     * 解析积分兑换数据
     *
     * @param dataInts
     * @return
     */
    private static SellMachineNetpay parseAisleInfo(int[] dataInts) {
        SellMachineNetpay sellMachineNetpay = new SellMachineNetpay();
        sellMachineNetpay.setNetPayType(dataInts[16]);
        sellMachineNetpay.setPayType(dataInts[17]);
        sellMachineNetpay.setAisle(parseAisle(dataInts));
        sellMachineNetpay.setDeviceId(parseDeviceId(dataInts, 4, 15));
        return sellMachineNetpay;
    }

    /**
     * 请求状态
     *
     * @param dataInts
     * @return
     */
    private static SellMachineNetpay parsePayStatus(int[] dataInts) {
        SellMachineNetpay sellMachineNetpay = parseSmjCardNo(dataInts);
        int len = parseDataLength(dataInts);
        sellMachineNetpay.setNetPayType(dataInts[16]);
        sellMachineNetpay.setDeviceId(parseDeviceId(dataInts, 4, 15));
        sellMachineNetpay.setOrderCode(parseOrderNo(dataInts));
        return sellMachineNetpay;
    }

    /**
     * 解析请求链接
     *
     * @param dataInts
     * @return
     */
    private static SellMachineNetpay parsePayUrl(int[] dataInts) {
        SellMachineNetpay sellMachineNetpay = new SellMachineNetpay();
        sellMachineNetpay.setNetPayType(dataInts[16]);
        sellMachineNetpay.setPayType(dataInts[17]);
        sellMachineNetpay.setAisle(parseAisle(dataInts));
        //sellMachineNetpay.setCardNo(parseCardNo(dataInts));
        sellMachineNetpay.setDeviceId(parseDeviceId(dataInts, 4, 15));
        return sellMachineNetpay;
    }

    /**
     * 解析时间
     *
     * @return
     */
    public static Date parseDate(int year, int month, int day, int hour, int min, int sec) throws ParseException {
        Calendar date = Calendar.getInstance();
        String yearStr = String.valueOf(date.get(Calendar.YEAR)).substring(0, 2);
        StringBuilder sb = new StringBuilder(yearStr);
        sb.append(year).append("-").append(month).append("-").append(day).append(" ").append(hour).append(":").append(min).append(":").append(sec);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return sdf.parse(sb.toString());
    }

    /**
     * 解析货道
     *
     * @param dataInts
     * @return
     */
    public static int parseAisle(int[] dataInts) {
        return DataHandler.unionLowHigh(dataInts[18], dataInts[19]) + 1;
    }

    /**
     * 解析卡号
     *
     * @param dataInts
     * @return
     */
    public static String parseCardNo(int[] dataInts) {
        return DataHandler.toCharArrayStr(DataHandler.subInts(dataInts, 20, parseDataLength(dataInts) - 3)).trim();
    }

    /**
     * 解析订单号
     *
     * @param dataInts
     * @return
     */
    public static String parseOrderNo(int[] dataInts) {
        return DataHandler.toCharArrayStr(DataHandler.subInts(dataInts, 17, dataInts.length - 3)).trim();
    }

    /**
     * 解析newReceive请求数据
     *
     * @param dataInts
     * @return
     */
    public static SellMachineNetpay newReceive(int[] dataInts) {
        switch (dataInts[16]) {

            case 0:
                //验证卡号
                return parseSmjCardNo(dataInts);
            case 1:
                //验证领取资格
                return parseSmjCardNo(dataInts);
            default:
                //其他类型不支持
                return null;
        }
    }


    /**
     * 卡号
     *
     * @param dataInts
     * @return
     */
    private static SellMachineNetpay parseSmjCardNo(int[] dataInts) {
        SellMachineNetpay sellMachineNetpay = new SellMachineNetpay();
        sellMachineNetpay.setNetPayType(dataInts[16]);
        String cardNo = DataHandler.toCharArrayStr(DataHandler.subInts(dataInts, 17, dataInts.length - 3));
        sellMachineNetpay.setCardNo(cardNo.trim());
        sellMachineNetpay.setDeviceId(parseDeviceId(dataInts, 4, 15));
        return sellMachineNetpay;
    }

}
